package com.jtw.common.util;

import com.github.pagehelper.PageHelper;
import com.google.common.base.CaseFormat;
import com.jtw.common.anno.findPagingAnno.FindPagingItemAnno;
import com.jtw.common.bean.enums.ReqCode;
import com.jtw.common.bean.vo.FindParamVo;
import com.jtw.common.bean.vo.PagingVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 分页工具
 * Created by keliii on 2018/7/17.
 */
@Slf4j
public class PagingUtil {

        public static void start(Object req) {
            if (req instanceof PagingVo) {
                PagingVo paging = (PagingVo) req;
                if (StringUtils.isNotBlank(paging.getOrderBy())) {
                    PageHelper.startPage(paging.getPage(), paging.getRows(), paging.getOrderBy());
                } else {
                    PageHelper.startPage(paging.getPage(), paging.getRows());
                }
            }
        }

        /**
         * 校验传递到接口的参数是否合法
         *
         * @param paramVo
         * @param pagingItemAnno
         * @return
         */
        public static void FilterParams(FindParamVo paramVo, FindPagingItemAnno[] pagingItemAnno) {
//            StringBuilder sb = new StringBuilder();
            boolean flag=false;
            for (FindPagingItemAnno findPagingItemAnno : pagingItemAnno) {

                if(findPagingItemAnno.notNull()){
                    if(StringUtils.isBlank(paramVo.getValue())){
                        throw ReqCode.FindParamsVoNoExitError.getException("请求参数不能为空");
                    }
                }
                //优先判断筛选的字段是否为允许的字段
                if (!findPagingItemAnno.column().equals(paramVo.getColumn())) {
                    continue;
                }
                log.info(findPagingItemAnno.column());
                log.info(findPagingItemAnno.conditions().toString());
                log.info(findPagingItemAnno.fixedValue().toString());
                log.info(findPagingItemAnno.prefix());
                log.info(paramVo.getPrefix());
                log.info(findPagingItemAnno.prefix().equals(paramVo.getPrefix())+"");
                log.info(findPagingItemAnno.isString()+"");
                flag=true;
                //查询的字段表前缀非法
                if (!findPagingItemAnno.prefix().equals("")&&!findPagingItemAnno.prefix().equals(paramVo.getPrefix())) {
                    throw ReqCode.FindParamsVoPrefixError.getException(paramVo.getPrefix());
                }
                //字段不能为空
                if (StringUtils.isBlank(paramVo.getColumn())) {
                    throw ReqCode.FindParamsVoColumnError.getException(paramVo.getColumn());
                }
                //字段的比对条件不能为空
                if (StringUtils.isBlank(paramVo.getCondition())) {
                    throw ReqCode.FindParamsVoConditionError.getException(paramVo.getCondition());
                }
                //比对条件非法
                if(!checkValueFixed(paramVo.getCondition(),findPagingItemAnno.conditions())){
                    throw ReqCode.FindParamsVoNoExitError.getException(paramVo.getCondition());
                }
                //字段的值不在允许范围
                if(!checkValueFixed(paramVo.getValue(),findPagingItemAnno.fixedValue())){
                    throw ReqCode.FindParamsVoValueError.getException(paramVo.getValue());
                }
            }
            if(!flag){
                //查询的字段不在允许范围之内
                throw ReqCode.FindParamsVoNoExitError.getException(paramVo.getColumn());
            }
        }
    /**
     * 将查询参数转换为数据库字段格式 供xml遍历使用
     * @param findParamVos
     * @return
     */
    public static List<FindParamVo> caseColumnToUPPER_CAMEL(List<FindParamVo> findParamVos){
            for(FindParamVo findParamVo:findParamVos){
                findParamVo.setColumn(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, findParamVo.getColumn()));
            }
            log.info("查询参数转换完毕"+findParamVos.toString());
            return findParamVos;
        }

    /**
     * 将查询参数直接创建为where条件语句 使用
     * @param findParamVos
     * @return
     */
    public static String buildWhereSQLToString(List<FindParamVo> findParamVos){
        StringBuilder sb = new StringBuilder(" WHERE 1=1 ");

        if(findParamVos==null){
            return sb.toString();
        }
        for (FindParamVo findParamVo : findParamVos) {
            if(StringUtils.isBlank(findParamVo.getValue())){
                continue;
            }

//            buildWhereSQL(sb,findParamVo,checkFieldTypeisString(findParamVo.getColumn(),classList));
            buildWhereSQL(sb,findParamVo);
        }
        log.info(sb.toString());
        return sb.toString();
    }

    /**
     * 将查询参数直接创建为where条件语句 使用
     * @param WhereSQL 需要添加的额外的where限制条件，不在查询字段中的
     * @param findParamVos
     * @return
     */
    public static String buildCustomeWhereSQLToString(String WhereSQL,List<FindParamVo> findParamVos){
        StringBuilder sb = new StringBuilder(" WHERE 1=1 "+ WhereSQL);

        if(findParamVos==null){
            return sb.toString();
        }
        for (FindParamVo findParamVo : findParamVos) {
            if(StringUtils.isBlank(findParamVo.getValue())){
                continue;
            }

//            buildWhereSQL(sb,findParamVo,checkFieldTypeisString(findParamVo.getColumn(),classList));
            buildWhereSQL(sb,findParamVo);
        }
        log.info(sb.toString());
        return sb.toString();
    }


    /**
     * 检测当前需要加入到筛选条件的字段数据类型是否为字符串
     * @param column
     * @param classList
     * @return
     */
//    private static boolean checkFieldTypeisString(String column,List<Class> classList) {
//        boolean flag = false;
//        for(Class cls :classList){
//            log.information("当前检测的类是"+cls);
//            Field fields [] = cls.getDeclaredFields();
//            for(Field field:fields){
//                if(field.getName().equals(column)){
//                    log.information("当前相同的字段是"+field.getName());
//                    log.information("当前字段的数据类型是"+field.getGenericType());
//                    if(field.getGenericType().equals(String.class)){
//                        log.information("当前字段的数据类型是"+field.getGenericType());
//                        flag=true;
//                        return flag;
//                    }
//                }
//            }
//        }
//        return flag;
//    }

    /**
     * 构建实际的查询语句
     * @param sb
     * @param paramVo
     * @return
     */
    public static StringBuilder buildWhereSQL(StringBuilder sb,FindParamVo paramVo){
        sb.append(" AND ");
        sb.append(paramVo.getPrefix());
        sb.append("`");
        //驼峰属性字段转化为数据库字段的大写下划线格式USER_NAME
        sb.append(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, paramVo.getColumn()));
        sb.append("`");
        sb.append(" ");
        sb.append(paramVo.getCondition());
        sb.append(" ");
        if(paramVo.getCondition().equals("LIKE")){
            sb.append("'%");
            sb.append(paramVo.getValue());
            sb.append("%'");
        }else{
            if(paramVo.getIsString()){
                sb.append("'");
                sb.append(paramVo.getValue());
                sb.append("'");
            }else{
                sb.append(paramVo.getValue());
            }
        }
        return sb;
    }


    public static boolean checkValueFixed(String str,String[] array){
            boolean flag = false;
            if(str==null){
                return flag;
            }
            if(array.length==0){
                flag=true;
            }
            for(String s :array){
               if(s.equals(str)){
                    flag=true;
               }
            }
            return flag;
    }
}